package com.example.port.service.impl;

import com.example.port.entity.Invoice;
import com.example.port.entity.StorageFee;
import com.example.port.exception.ResourceNotFoundException;
import com.example.port.mapper.InvoiceMapper;
import com.example.port.mapper.StorageFeeMapper;
import com.example.port.service.InvoiceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
public class InvoiceServiceImpl implements InvoiceService {
    
    private final InvoiceMapper invoiceMapper;
    private final StorageFeeMapper storageFeeMapper;
    
    @Autowired
    public InvoiceServiceImpl(InvoiceMapper invoiceMapper, StorageFeeMapper storageFeeMapper) {
        this.invoiceMapper = invoiceMapper;
        this.storageFeeMapper = storageFeeMapper;
    }
    
    @Override
    public int insertInvoice(Invoice invoice) {
        // 检查是否已设置ID，如果没有，则自动生成ID
        if (invoice.getInvoiceId() == null) {
            Long maxId = invoiceMapper.getMaxInvoiceId();
            invoice.setInvoiceId(maxId + 1);
        }
        return invoiceMapper.insert(invoice);
    }
    
    @Override
    public List<Invoice> getAllInvoices() {
        return invoiceMapper.selectAll();
    }
    
    @Override
    public Invoice getInvoiceById(Long invoiceId) {
        Invoice invoice = invoiceMapper.selectById(invoiceId);
        if (invoice == null) {
            throw new ResourceNotFoundException("找不到ID为" + invoiceId + "的发票");
        }
        return invoice;
    }
    
    @Override
    public List<StorageFee> getInvoiceFees(Long invoiceId) {
        // 先验证发票是否存在
        try {
            Invoice invoice = getInvoiceById(invoiceId);
            System.out.println("获取发票关联费用，发票ID: " + invoiceId + ", 发票状态: " + invoice.getStatus());
            
            // 获取关联的费用
            List<StorageFee> fees = invoiceMapper.selectInvoiceFees(invoiceId);
            System.out.println("发票关联费用数量: " + (fees != null ? fees.size() : 0));
            
            // 如果没有找到关联费用，尝试通过StorageFeeMapper直接查询
            if (fees == null || fees.isEmpty()) {
                System.out.println("通过InvoiceMapper未找到费用，尝试通过StorageFeeMapper查询");
                fees = storageFeeMapper.selectByInvoiceId(invoiceId);
                System.out.println("通过StorageFeeMapper找到费用数量: " + (fees != null ? fees.size() : 0));
            }
            
            return fees;
        } catch (Exception e) {
            System.err.println("获取发票关联费用时发生错误: " + e.getMessage());
            e.printStackTrace();
            return null;
        }
    }
    
    @Override
    @Transactional
    public int issueInvoice(Long invoiceId) {
        // 先验证发票是否存在
        Invoice invoice = getInvoiceById(invoiceId);
        
        if ("已开票".equals(invoice.getStatus())) {
            // 如果已开票，返回成功但不做更改
            return 1;
        }
        
        if (!"未开票".equals(invoice.getStatus())) {
            // 只有未开票状态的发票可以开具
            return 0;
        }
        
        // 更新发票状态为已开票
        invoice.setStatus("已开票");
        
        return invoiceMapper.update(invoice);
    }
    
    @Override
    @Transactional
    public int generateInvoiceFromStorageFees(List<Long> storageFeeIds, Integer clientId) {
        // 验证费用列表是否为空
        if (storageFeeIds == null || storageFeeIds.isEmpty()) {
            return 0;
        }
        
        // 获取所有相关费用
        BigDecimal totalAmount = BigDecimal.ZERO;
        Date startDate = null;
        Date endDate = null;
        
        for (Long feeId : storageFeeIds) {
            StorageFee fee = storageFeeMapper.selectById(feeId);
            if (fee == null) {
                throw new ResourceNotFoundException("找不到ID为" + feeId + "的仓储费用");
            }
            
            // 累加金额
            totalAmount = totalAmount.add(fee.getFeeAmount());
            
            // 更新费用开始和结束日期
            if (startDate == null || fee.getCalculationDate().before(startDate)) {
                startDate = fee.getCalculationDate();
            }
            
            // 使用计算日期+天数来确定结束日期
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(fee.getCalculationDate());
            calendar.add(Calendar.DAY_OF_MONTH, fee.getDaysCounted());
            Date feeEndDate = calendar.getTime();
            
            if (endDate == null || feeEndDate.after(endDate)) {
                endDate = feeEndDate;
            }
        }
        
        // 创建发票
        Invoice invoice = new Invoice();
        invoice.setClientId(clientId);
        invoice.setInvoiceDate(new Date()); // 当前日期为发票日期
        invoice.setStartDate(startDate);
        invoice.setEndDate(endDate);
        invoice.setTotalAmount(totalAmount);
        invoice.setStatus("未开票");
        
        // 设置到期日期（30天后）
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, 30);
        invoice.setDueDate(calendar.getTime());
        
        // 自动生成ID
        Long maxId = invoiceMapper.getMaxInvoiceId();
        invoice.setInvoiceId(maxId + 1);
        
        // 保存发票
        int result = invoiceMapper.insert(invoice);
        
        if (result > 0) {
            // 将费用与发票关联
            for (Long feeId : storageFeeIds) {
                // 明确调用关联方法
                invoiceMapper.linkFeeToInvoice(feeId, invoice.getInvoiceId());
                
                // 更新费用状态
                StorageFee fee = storageFeeMapper.selectById(feeId);
                if (fee != null) {
                    // 只有在费用状态不是"已支付"时才设置为"已支付"
                    if (!"已支付".equals(fee.getPaymentStatus())) {
                        fee.setPaymentStatus("已支付");
                    }
                    // 确保设置了发票ID
                    fee.setInvoiceId(invoice.getInvoiceId());
                    storageFeeMapper.update(fee);
                    
                    // 打印日志以便调试
                    System.out.println("关联费用ID: " + feeId + " 到发票ID: " + invoice.getInvoiceId());
                }
            }
        }
        
        return result;
    }
    
    @Override
    public int deleteInvoice(Long invoiceId) {
        // 先验证发票是否存在
        Invoice invoice = null;
        try {
            invoice = invoiceMapper.selectById(invoiceId);
            System.out.println("准备删除发票，ID:" + invoiceId + "，发票数据:" + (invoice != null ? "存在" : "不存在"));
        } catch (Exception e) {
            System.err.println("查询发票时发生错误: " + e.getMessage());
            e.printStackTrace();
        }
        
        if (invoice == null) {
            System.out.println("未找到ID为" + invoiceId + "的发票，无法删除");
            return 0;
        }
        
        // 删除发票（数据库外键会自动处理fees的关联）
        try {
            int result = invoiceMapper.delete(invoiceId);
            System.out.println("删除发票结果，ID:" + invoiceId + "，结果:" + (result > 0 ? "成功" : "失败"));
            return result;
        } catch (Exception e) {
            System.err.println("删除发票时发生错误: " + e.getMessage());
            e.printStackTrace();
            return 0;
        }
    }
    
    @Override
    public int unlinkFeeFromInvoice(Long feeId) {
        // 解除费用与发票的关联
        return invoiceMapper.unlinkFee(feeId);
    }
} 
